package com.ruoyi.web.controller.wxpay;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.core.config.WxPayConfig;
import com.ruoyi.web.core.service.WxPayService;
import com.ruoyi.web.domain.dto.WxPayRequest;
import com.ruoyi.web.domain.dto.WxPayQueryRequest;
import com.ruoyi.web.domain.vo.WxPayResponse;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;

/**
 * 微信支付控制器
 * 
 * @author ruoyi
 */
@Api(tags = "微信支付管理")
@RestController
@RequestMapping("/wxpay")
@Validated
public class WxPayController extends BaseController {
    
    private static final Logger log = LoggerFactory.getLogger(WxPayController.class);
    
    @Autowired
    private WxPayService wxPayService;
    
    @Autowired
    private WxPayConfig wxPayConfig;
    

    
    /**
     * 创建预支付订单
     * 
     * @param request 创建订单请求
     * @return 预支付响应
     */
    @ApiOperation(value = "创建预支付订单", notes = "创建微信支付预支付订单")
    @Log(title = "微信支付", businessType = BusinessType.INSERT)
    @PostMapping("/create")
    public WxPayResponse createOrder(@Valid @RequestBody WxPayRequest request) {
        log.info("=== WxPayController：接收到创建预支付订单请求 ===");
        log.info("请求对象是否为null: {}", request == null);
        if (request != null) {
            log.info("订单号: {}", request.getOutTradeNo());
            log.info("金额: {}分", request.getTotalAmount());
            log.info("openid: {}", request.getOpenid());
            log.info("orgId: {}", request.getOrgId());
            log.info("wechatAppId: {}", request.getWechatAppId());
            log.info("完整请求对象: {}", request.toString());
        }
        
        try {
             
             // 调用微信支付服务创建预支付订单
              PrepayWithRequestPaymentResponse response = wxPayService.createPrepayOrder(
                  request.getOutTradeNo(),
                  request.getDescription(),
                  WxPayRequest.fenToYuan(request.getTotalAmount()),
                  request.getOpenid(),
                  request.getWechatAppId(),
                  request.getOrgId(),
                  wxPayConfig.getPayNotifyUrl()
              );
            
            return WxPayResponse.success("创建预支付订单成功", response);
            
        } catch (Exception e) {
             log.error("创建预支付订单失败，订单号：{}，错误信息：{}", request.getOutTradeNo(), e.getMessage(), e);
             return WxPayResponse.error("创建预支付订单失败：" + e.getMessage());
         }
    }
    
    /**
     * 微信支付回调通知
     * 
     * @param request HTTP请求
     * @return 处理结果
     */
    @ApiOperation(value = "微信支付回调通知", notes = "处理微信支付回调通知")
    @PostMapping("/payNotify")
    public synchronized String payNotify(HttpServletRequest request) {
        try {
            log.info("------收到微信支付通知------");
            
            // 获取请求头信息
            String signature = request.getHeader("Wechatpay-Signature");
            String nonce = request.getHeader("Wechatpay-Nonce");
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            String serial = request.getHeader("Wechatpay-Serial");
            String signType = request.getHeader("Wechatpay-Signature-Type");
            
            // 获取请求体
            String requestBody = request.getReader().lines()
                    .collect(Collectors.joining(System.lineSeparator()));
            
            log.info("微信支付回调请求头 - Signature: {}, Nonce: {}, Timestamp: {}, Serial: {}, SignType: {}", 
                    signature, nonce, timestamp, serial, signType);
            
            // 处理支付回调
            boolean success = wxPayService.handlePayNotify(requestBody, signature, nonce, timestamp, serial, signType);
            
            if (success) {
                log.info("微信支付回调处理成功");
                return "{\"code\":\"SUCCESS\",\"message\":\"成功\"}";
            } else {
                log.error("微信支付回调处理失败");
                return "{\"code\":\"FAIL\",\"message\":\"失败\"}";
            }
            
        } catch (IOException e) {
            log.error("读取微信支付回调请求体失败，错误信息：{}", e.getMessage(), e);
            return "{\"code\":\"FAIL\",\"message\":\"读取请求体失败\"}";
        } catch (Exception e) {
            log.error("处理微信支付回调异常，错误信息：{}", e.getMessage(), e);
            return "{\"code\":\"FAIL\",\"message\":\"处理异常\"}";
        }
    }
    
    /**
     * 查询订单支付状态
     * 
     * @param request 查询请求参数
     * @return 订单状态
     */
    @ApiOperation(value = "查询订单支付状态", notes = "查询订单在微信支付的状态")
    @PostMapping("/queryOrder")
    public WxPayResponse queryOrder(@Valid @RequestBody WxPayQueryRequest request) {
        try {
            log.info("查询订单支付状态，订单号：{}", request.getOutTradeNo());
            JSONObject result = wxPayService.queryOrderStatus(
                request.getOutTradeNo(),
                request.getOrgId(),
                request.getWechatAppId()
            );
            
            return WxPayResponse.success("查询订单状态成功", result);
            
        } catch (Exception e) {
            log.error("查询订单支付状态失败，订单号：{}，错误信息：{}", request.getOutTradeNo(), e.getMessage(), e);
            return WxPayResponse.error("查询订单支付状态失败: " + e.getMessage());
        }
    }

    /**
     * 获取微信商户公开信息（例如 merchant_id），供前端组件（weappOrderConfirm）使用
     */
    @ApiOperation(value = "获取商户公开信息", notes = "按 orgId + wechatAppId 返回商户公开信息")
    @GetMapping("/merchant/publicInfo")
    public WxPayResponse getMerchantPublicInfo(
            @ApiParam(value = "组织ID", required = true) @RequestParam("orgId") String orgId,
            @ApiParam(value = "微信AppID", required = true) @RequestParam("wechatAppId") String wechatAppId) {
        try {
            JSONObject result = wxPayService.getMerchantPublicInfo(orgId, wechatAppId);
            return WxPayResponse.success("查询成功", result);
        } catch (Exception e) {
            log.error("获取商户公开信息失败，orgId={}, appId={}, 错误信息：{}", orgId, wechatAppId, e.getMessage(), e);
            return WxPayResponse.error("获取商户公开信息失败: " + e.getMessage());
        }
    }
}
